﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Twodi.Implemented;
using System.ComponentModel;
using Twodi.Behavior.Interfaces;

namespace Twodi.Behavior.Implemented
{
    /// <summary>
    /// Define o gerenciamento das animações.
    /// </summary>
    public class AnimateBehavior : AbstractBehavior<IAnimationBehavior>
    {
        protected int animationIndex = -1;

        protected BindingList<AnimationBehavior> animations;

        public AnimateBehavior(IAnimationBehavior component)
            : base(component)
        {
            Animations = new BindingList<AnimationBehavior>();

            Animations.ListChanged += (sender, e) =>
            {
                AnimationBehavior newAnimation = Animations[e.NewIndex];

                if (Animations.Count == 1)
                {
                    animationIndex = 0;
                    this.Component.TextureProperties.Source = newAnimation.Frame.Source;
                }
            };
        }

        public override void Initialize()
        {
            return;
        }

        public override void Update(GameTime gameTime)
        {
            if (Animation != null)
            {
                Animation.Update(gameTime);
            }
            return;
        }

        public override void Draw(GameTime gameTime)
        {
            return;
        }

        public override bool Handle(Input.KeyboardInput input)
        {
            throw new NotImplementedException();
        }

        public override bool Handle(Input.MouseInput input)
        {
            throw new NotImplementedException();
        }

        public int AnimationIndex
        {
            get { return this.animationIndex; }
            set
            {
                this.animationIndex = value;
                onAnimationIndexChanged(EventArgs.Empty);
            }
        }

        public String AnimationName
        {
            get { return this.Animations[AnimationIndex].Name; }
            set
            {
                int previous = AnimationIndex;
                AnimationIndex = -1;
                for (int i = 0; i < Animations.Count; i++)
                {
                    if (Animations[i].Name.ToUpper() == value.ToUpper())
                    {
                        AnimationIndex = i;
                        onAnimationNameChanged(EventArgs.Empty);
                        break;
                    }
                }

                if (AnimationIndex == -1)
                {
                    throw new Exception("Animation not found.");
                }
                else if (previous != AnimationIndex)
                {
                    Animation.Reset();
                }
            }
        }

        public AnimationBehavior Animation
        {
            get
            {
                return this.Animations[AnimationIndex];
            }
        }

        public BindingList<AnimationBehavior> Animations
        {
            get { return this.animations; }
            set
            {
                this.animations = value;
                onAnimationsChanged(EventArgs.Empty);
            }
        }

        public event EventHandler<EventArgs> AnimationIndexChanged;

        public event EventHandler<EventArgs> AnimationNameChanged;

        public event EventHandler<EventArgs> AnimationsChanged;

        protected virtual void onAnimationIndexChanged(EventArgs e)
        {
            if (AnimationIndexChanged != null)
            {
                AnimationIndexChanged(this, e);
            }
        }

        protected virtual void onAnimationNameChanged(EventArgs e)
        {
            if (AnimationNameChanged != null)
            {
                AnimationNameChanged(this, e);
            }
        }

        protected virtual void onAnimationsChanged(EventArgs e)
        {
            if (AnimationsChanged != null)
            {
                AnimationsChanged(this, e);
            }
        }
    }
}
